回顧第10天,effect
追蹤signal
並在任何signal
值更新時運行effect
函數。當signal
不是effect
的依賴項時,它會呼叫未追蹤的函數以防止訊號讀取。我對效果的主要挑戰是識別不應被視為效果函數依賴項的訊號。 當我發現ngXtension
庫中的explicitEffect
函數時,追蹤signal
值得到了極大的簡化。 當dependency array
中的signal
發生變化時,explicitEffect
函數才運行effect
函數。
今天,我想用explicitEffect
重寫第10天的effect
例子。
npm i ngxtension
import { explicitEffect } from 'ngxtension/explicit-effect';
// character.component.ts
effect((onCleanUp) => {
const sub = getPersonMovies(this.id(), this.injector)
.subscribe((result) => {
if (result) {
const [person, ...rest] = result;
this.person.set(person);
this.films.set(rest);
} else {
this.person.set(undefined);
this.films.set([]);
}
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
onCleanUp(() => sub.unsubscribe());
});
constructor() {
explicitEffect([this.id], ([id], onCleanUp) => {
const sub = getPersonMovies(id, this.injector)
.subscribe((result) => {
if (result) {
const [person, ...rest] = result;
this.person.set(person);
this.films.set(rest);
} else {
this.person.set(undefined);
this.films.set([]);
}
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
onCleanUp(() => sub.unsubscribe());
});
}
只有當dependency array
的id
signal發生變更時,explicitEffect
才會運作。 explicitEffect
的第二個參數是執行explicitEffect
邏輯的函數。 onCleanUp
是一個explicitEffect
清理函數,它在銷毀effect
之前取消subscription
。
untracked(() => {
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
});
#logIDsEffect = effect(() => console.log('id ->', untracked(this.id), 'searchID ->', this.searchId()));
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
explicitEffect
不會明確追蹤searchId
signal,因此不需要呼叫untracked
函數來執行外部程式碼。
#logIDsEffect = explicitEffect([this.searchId], ([searchId]) => console.log('id ->', this.id(), 'searchID ->', searchId),
{ defer: true });
我創建了一個新的explicitEffect
來追蹤dependency array
中的searchId
signal。 explicitEffect
函數記錄id
和searchId
的值。 新增第三個參數{ defer: rue }
以延遲effect
,直到searchId
發生變更。
searchId = signal(initialId);
首次初始化searchId
signal時沒有日誌訊息。
if (this.id() !== this.searchId()) {
this.searchId.set(this.id());
}
<input type="number" [(ngModel)]="searchId" name="searchId" id="searchId" />
當searchId
signal變更時,將記錄該訊息。
this.renderer.setProperty(this.hostElement, 'style', `--main-font-size: ${untracked(this.fontSize)}`);
#rgbEffect = effect(() => console.log('rgb ->', this.rgb()));
this.renderer.setProperty(this.hostElement, 'style', `--main-font-size: ${this.fontSize()}`);
explicitEffect
不會明確追蹤fontSize
signal,因此,它不需要呼叫untracked
函數來取得值。
#rgbEffect = explicitEffect([this.rgb], ([rgb]) => console.log('rgb ->', rgb), { defer: true });
我創建了一個新的explicitEffect
來追蹤dependency array
的rgb
signal。 explicitEffect
函數記錄rgb
值。 新增第三個參數{ defer: rue }
以延遲effect
,直到rgb
發生變更。
rgb = signal('brown');
首次初始化rgb
signal時沒有日誌訊息。
const sub = getPersonMovies(id, this.injector)
.subscribe((result) => {
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
this.rgb.set(generateRGBCode());
});
設定rgb
signal後,將記錄該訊息。
鐵人賽第11天就這樣結束了。